package it.eng.area118.mdocommon.android.activity;

import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantLock;

import it.eng.area118.mdocommon.android.animation.SlideAnimations;
import it.eng.area118.mdocommon.android.log.BasicLogger;
import it.eng.area118.mdocommon.android.util.AndroidApplicationContext;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.widget.ViewFlipper;

public class SlideActivityController implements
		GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener {

	private final static String TAG = SlideActivityController.class.getName();

	protected final int SWIPE_MIN_DISTANCE = 100;
	protected final int SWIPE_MIN_VELOCITY = 100;

	private ViewFlipper flipper;

	private SlideActivityControllerListener listener;

	private AtomicReference<Boolean> isScrolling = new AtomicReference<Boolean>(false);

	private boolean flingMode = false;

	// private int currentview;

	public SlideActivityController(ViewFlipper flipper) {
		this.flipper = flipper;

	}

	@Override
	public boolean onDoubleTap(MotionEvent arg0) {
		BasicLogger.writeLog(TAG, "onDoubleTap");
		// flipper.scrollTo(0, 0);
		// isDragMode = false;
		return false;
	}

	@Override
	public boolean onDoubleTapEvent(MotionEvent e) {
		BasicLogger.writeLog(TAG, "onDoubleTapEvent");
		return false;
	}

	@Override
	public boolean onSingleTapConfirmed(MotionEvent e) {
		BasicLogger.writeLog(TAG, "onSingleTapConfirmed");
		return false;
	}

	@Override
	public boolean onDown(MotionEvent e) {
		BasicLogger.writeLog(TAG, "onDown");
		// updateCurrentView();
		return false;
	}

	// protected abstract void updateCurrentView();

	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
			float distanceY) {
		flingMode  = false;
		isScrolling.set(true);
		final float ev1x = e1.getX();
		final float ev1y = e1.getY();
		final float ev2x = e2.getX();
		final float ev2y = e2.getY();
		final float xdiff = Math.abs(ev1x - ev2x);
		final float ydiff = Math.abs(ev1y - ev2y);
		// final float xvelocity = Math.abs(velocityX);
		// final float yvelocity = Math.abs(velocityY);

		BasicLogger.writeLog(TAG, "onScroll event1: " + ev1x);
		BasicLogger.writeLog(TAG, "onScroll event2: " + ev2x);
		BasicLogger.writeLog(TAG, "onScroll xdiff: " + xdiff);
		BasicLogger.writeLog(TAG, "onScroll distanceX: " + distanceX);

		// flipper.getCurrentView().scrollTo((int)ev2x, 0);
		flipper.getCurrentView().scrollBy((int) distanceX, 0);

		return false;
	}

	protected void doSlideActivityFling(MotionEvent e1, MotionEvent e2,
			float velocityX, float velocityY) {
		BasicLogger.writeLog(TAG, "onFling");
		final float ev1x = e1.getX();
		final float ev1y = e1.getY();
		final float ev2x = e2.getX();
		final float ev2y = e2.getY();
		final float xdiff = Math.abs(ev1x - ev2x);
		final float ydiff = Math.abs(ev1y - ev2y);
		final float xvelocity = Math.abs(velocityX);
		final float yvelocity = Math.abs(velocityY);

		// if (!isDragMode) {
		if (xvelocity > this.SWIPE_MIN_VELOCITY
				&& xdiff > this.SWIPE_MIN_DISTANCE) {
			if (ev1x > ev2x) // Swipe Left
			{
				previous();
			} else // Swipe Right
			{
				next();
			}

			flipper.scrollTo(0, 0);			
			View view = flipper.getCurrentView();
			view.scrollTo(0, 0);
			if (listener != null) {
				listener.onSlideProcessed();
			}
		}
	}

	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
			float velocityY) {
		BasicLogger.writeLog(TAG, "ON FLING");
		flingMode = true;
		isScrolling.set(false);
		
		doSlideActivityFling(e1, e2, velocityX, velocityY);
		return false;
	}

	@Override
	public void onLongPress(MotionEvent e) {
		BasicLogger.writeLog(TAG, "onLongPress");
		// isDragMode = !isDragMode;
	}

	@Override
	public void onShowPress(MotionEvent e) {
		BasicLogger.writeLog(TAG, "onShowPress");

	}

	@Override
	public boolean onSingleTapUp(MotionEvent e) {
		BasicLogger.writeLog(TAG, "onSingleTapUp");
		return false;
	}

	public Animation getAnimleftin() {
		SlideActivity theSlideActivity = (SlideActivity) AndroidApplicationContext
				.getInstance().getApplicationContextValue(
						SlideActivity.class.toString());
		return theSlideActivity.getAnimleftin();

	}

	public Animation getAnimleftout() {
		SlideActivity theSlideActivity = (SlideActivity) AndroidApplicationContext
				.getInstance().getApplicationContextValue(
						SlideActivity.class.toString());
		return theSlideActivity.getAnimleftout();
	}

	public Animation getAnimrightin() {
		SlideActivity theSlideActivity = (SlideActivity) AndroidApplicationContext
				.getInstance().getApplicationContextValue(
						SlideActivity.class.toString());
		return theSlideActivity.getAnimrightin();
	}

	public Animation getAnimrightout() {
		SlideActivity theSlideActivity = (SlideActivity) AndroidApplicationContext
				.getInstance().getApplicationContextValue(
						SlideActivity.class.toString());
		return theSlideActivity.getAnimrightout();
	}

	protected void previous() {
		// --currentview;
		setCurrentView(getCurrentView() - 1);
		if (getCurrentView() < 0) {
			// currentview = views.size() - 1;
			setCurrentView(getViewSize() - 1);
		}
		flipper.setInAnimation(getAnimleftin());
		flipper.setOutAnimation(getAnimleftout());
		this.flipper.setDisplayedChild(getCurrentView());
	}

	protected void next() {
		// ++currentview;
		setCurrentView(getCurrentView() + 1);
		if (getCurrentView() >= getViewSize()) {
			setCurrentView(0);
		}
		flipper.setInAnimation(getAnimrightin());
		flipper.setOutAnimation(getAnimrightout());
		
		this.flipper.setDisplayedChild(getCurrentView());
	}

	private int getViewSize() {
		SlideActivity theSlideActivity = (SlideActivity) AndroidApplicationContext
				.getInstance().getApplicationContextValue(
						SlideActivity.class.toString());
		return theSlideActivity.getViewSize();
	}

	private int getCurrentView() {
		SlideActivity theSlideActivity = (SlideActivity) AndroidApplicationContext
				.getInstance().getApplicationContextValue(
						SlideActivity.class.toString());
		return theSlideActivity.getCurrentView();
	}

	private void setCurrentView(int index) {
		SlideActivity theSlideActivity = (SlideActivity) AndroidApplicationContext
				.getInstance().getApplicationContextValue(
						SlideActivity.class.toString());
		theSlideActivity.setCurrentView(index);
	}

	public SlideActivityControllerListener getListener() {
		return listener;
	}

	public void setListener(SlideActivityControllerListener listener) {
		this.listener = listener;
	}

	public boolean isScrolling() {
		return isScrolling.get();
	}

	public void setScrolling(boolean isScrolling) {
		this.isScrolling.set(isScrolling);
	}

	public boolean isFlingMode() {
		return flingMode;
	}

	public void setFlingMode(boolean flingMode) {
		this.flingMode = flingMode;
	}
	
	

}
